home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir41
/
wcpu050.zip
/
WCPU.ASM
next >
Wrap
Assembly Source File
|
1993-03-12
|
18KB
|
411 lines
; TASM 2.0 required
quirks
masm51
code SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:code
public GetProz,CoPro,DXorSX
;**********************************************************************;
;* P R O Z P A *;
;*--------------------------------------------------------------------*;
;* Aufgabe : Ermittelt den Typ von Prozessor, der in einem *;
;* PC installiert ist. *;
;* In dieser Version ist das Programm zur Um- *;
;* wandlung in INLINE-Befehle und damit zur Ein- *;
;* bindung in ein PASCAL-Programm vorgesehen. *;
;*--------------------------------------------------------------------*;
;* Autor : MICHAEL TISCHER *;
;* entwickelt am : 22.08.1988 *;
;* letztes Update : 22.08.1988 *;
;* *;
;* Modifiziert von Michael Holin (486,Pentium-Erkennung) *;
;* *;
;**********************************************************************;
;== Konstanten =========================================================
p_pentium equ 9
p_80486 equ 8
p_80386 equ 7
p_80386sx equ 7 ;Codes für die verschiedenen Pro-
p_80286 equ 6 ;zessortypen
p_80186 equ 5
p_80188 equ 4
p_v30 equ 3
p_v20 equ 2
p_8086 equ 1
p_8088 equ 0
;fernen haben die Bits 5-7 folgende Bedeutung:
;
; 8 7 6 5 | 4 3 2 1
; Weitek-Coprozessor vorhanden ──────┘ │ │
; Coprozessor wird emuliert ───────────┘ │
; CPU ist im Virtual Mode ───────────────┘
;== Code ===============================================================
getproz proc far ;diese Prozedur ist das eigentliche
;Hauptprogramm
push bp
mov bp,sp
pushf ;den Inhalt des Flag-Registers sichern
push cx ;den Inhalt aller veränderten Register
push dx ;auf dem Stack sichern
push di
push si
push es
;-- auf 80386/80286 testen -----------------------------------
xor ax,ax ;AX auf 0 setzen
push ax ;und auf den Stack bringen
popf ;als Flag-Register vom Stack holen
pushf ;wieder auf den Stack bringen
pop ax ;und als AX zurückholen
and ax,0f000h ;nur die oberen 4 Bits nicht löschen
cmp ax,0f000h ;sind die Bits 12 - 15 alle gleich 1?
je nicht_386 ;JA, kann kein 80386 oder 80286 sein
;-- testen, ob es sich um 80386 oder 80286 handelt -----------
mov dl,p_80286 ;es handelt sich auf jeden Fall um
mov ax,07000h ;einen der Beiden Prozessoren
push ax ;den Wert 07000h auf den Stack bringen
popf ;als Flag-Register zurückholen
pushf ;und wieder auf den Stack bringen
pop ax ;in das AX-Register zurückholen
and ax,07000h ;nur die Bits 12 - 14 nicht ausblenden
je pende ;sind die Bits 12 - 14 alle gleich 0?
;JA --> es handelt sich um einen 80286
inc dl ;Nein, es handelt sich um einen 80386
;oder 80486
.386p
call is486 ;Test auf 486 und Pentium
smsw bx
test bl,4 ;Koprozessor-Emulation ?
jz short @f
or dl,32 ;JA, dann 32 draufaddieren
@@: test bl,1 ;CPU in Virtual Mode ?
jz short @f
or dl,16 ;JA, dann 16 draufaddieren
@@: xor eax,eax
int 11h ;Weitek-Prozessor installiert?
test eax,1000000h
jz pende
or dl,64 ;dann 64 draufaddieren
; jmp pende
pende: ;die Testes sind abgeschlossen
xor ax,ax
mov al,dl ;Proz.Code in Return-Var. ablegen
pop es ;die gesicherten Register wieder vom
pop si ;Stack holen
pop di
pop dx
pop cx
popf ;Flag-Register wieder vom Stack holen
jmp ende ;zurück zum Aufrufer
;-- auf 80186 bzw. 80188 testen ------------------------------
nicht_386:
mov dl,p_80188 ;Code für 80188 laden
mov al,0ffh ;alle Bits im AL-Register auf 1 setzen
mov cl,021h ;Anzahl der Shift-Operationen nach CL
shr al,cl ;AL CL mal nach rechts verschieben
jne short t88_86 ;AL ist nicht 0, es muß sich um den
;80188 oder 80186 handeln
;-- auf NEC V20 oder V30 testen ------------------------------
mov dl,p_v20 ;Code für NEC V20 laden
sti ;Interrupts sollen erlaubt sein
mov si,0 ;mit dem ersten Byte in ES beginnen
mov cx,0ffffh ;ein komplettes Segment lesen
rep lods byte ptr es:[si] ;REP mit einem Segment-Override
;funktioniert nur bei NEC V20, V30
or cx,cx ;wurde das komplette Segment gelesen?
je t88_86 ;JA --> ist V20 oder V30
mov dl,p_8088 ;NEIN --> muß 8088 oder 8086 sein
;-- auf ...88 oder ...86 bzw. V20 oder V30 testen ------------
t88_86:
push cs ;CS auf dem Stack merken
pop es ;und als ES zurückholen
std ;bei Stringbefehlen abwärts zählen
mov al,0fbh ;Befehlscode für "STI"
mov cx,3 ;den Stringbefehl 3 mal ausführen
call get_di ;Startadresse DI holen
t86_1: cli ;Interrupts unterdrücken
rep stosb
cld ;bei Stringbefehlen wieder aufwärts
nop ;Dummy-Befehle zum Queue füllen
nop
nop
inc dx ;Prozessorcode inkrementieren
nop
q_end: sti ;Interrupts wieder erlauben
jmp pende
;-------------------------------------------------------------
getproz endp ;Ende der PROG-Prozedur
is486 proc ;-- Der folgende Test zwischen 80386 und 80486 beruht auf ----
;-- einer Erweiterung des EFlags-Registers beim 80486 in
;-- Bitposition 18.
;-- Dieses Flag gibt es beim 80386 nicht, und deshalb läßt
;-- sich sein Inhalt auch nicht per Software verändern.
cli ;keine Interrupts jetzt
mov ebx,esp ;aktuelles SP merken
and esp,0FFFCh ;auf DWORD abrunden
pushfd ;Flag-Register über
pop eax ;Stack nach AX
mov ecx,eax ;und in CX merken
xor eax,1 shl 18 ;Alignment-Bit umdrehen
push eax ;und in das Flag-
popfd ;Register bringen
pushfd ;Flag wieder auf Stack
pop eax ;und dann nach AX
push ecx ;alten Flag-Inhalt
popfd ;wieder zurück
xor eax,ecx ;AL-Bit testen
shr eax,18 ;AL-Bit nach Bit 0
and eax,1h ;alle anderen ausbl.
mov esp,ebx ;SP wieder zurücks.
add dl,al ;AL ist 1, wenn 486
mov ebx,esp ;aktuelles SP merken
and esp,0FFFCh ;auf DWORD abrunden
pushfd ;Flag-Register über
pop eax ;Stack nach AX
mov ecx,eax ;und in CX merken
xor eax,1 shl 21 ;ID-Bit umdrehen
push eax ;und in das Flag-
popfd ;Register bringen
pushfd ;Flag wieder auf Stack
pop eax ;und dann nach AX
push ecx ;alten Flag-Inhalt
popfd ;wieder zurück
xor eax,ecx ;AL-Bit testen
shr eax,21 ;AL-Bit nach Bit 0
and eax,1h ;alle anderen ausbl.
mov esp,ebx ;SP wieder zurücks.
sti ;Interrupts wieder erlauben
add dl,al ;AL ist 1, wenn Pentium
ret
is486 endp
;-- GET_DI ermittelt DI für 88/86-Test ---------------------------------
get_di:
pop di ;Rücksprungadresse vom Stack holen
add di,9 ;9 Bytes davon entfernt anfangen
jmp t86_1 ;wieder in die Testroutine springen
ende:
mov sp,bp
pop bp
ret
.8086
;== Ende ===============================================================
.386
DXorSX proc far ;Mem-Access via DWord-Read
assume cs:CODE, es:nothing
push bp
mov bp,sp
push ds
push es
push si
push di
push cx
pushf
mov ax,0040h
mov ds,ax
mov bx,00F0h
xor ecx,ecx
xor esi,esi
mov cx,word ptr ds:bx ;Anzahl
mov si,word ptr ds:bx + 2 ;Offset
mov ax,word ptr ds:bx + 4 ;Segment
mov ds,ax
cld
cli
mov al,34h
out 43h,al
jmp $+2
mov al,0
out 40h,al
jmp $+2
out 40h,al
rep
lodsd
mov al,0
out 43h,al
sti
jmp $+2
in al,40h
xchg ah,al
jmp $+2
in al,40h
xchg ah,al
neg ax ;return time for doing the loop
popf
pop cx
pop di
pop si
pop es
pop ds
mov sp,bp
pop bp
ret
DXorSX endp
.8086
; calling convention:
;
; function CoPro:word;
;
; returns:
;
; tucked away neatly in your AX....
;
; 0 if NO NDP is found
; 1 if an 8087
; 2 if an 80287
; 3 if an 80387
;
; NOTE:
;
; There are lotsa ways of handling the way this function returns
; it's data. For my purposes, I have elected this one because
; it requires only int arithmetic on the caller's end to extract
; all the info I need from the return value. I think that I'm
; well enough 'commented' in the following code so that you will
; be able to tinker and Putz until you find the best return tech-
; nique for Ur purposes without having to reinvent the wheel.
;
; REFERENCES:
;
; ndp_type is adopted from Ted Forgeron's article in PC
; Tech Journal, Aug '87 p43.
;
; In the event of subsequent republication of this function,
; please carry forward reference to these two gentlemen as
; original authors.
;
; Copr. 1987 Pat Shea - Psi! (that Copr. is on there cuz my
; lawyer sez I should, but feel
; free to hack away!!! pats.)
;
; Update: 1/1/88 - changed this code slightly so that it is
; compilable using MASM 5.0, and the test.c
; file using MSC 5.0. <Albert Stein>
;
CoPro proc far
assume cs:CODE, es:nothing
push BP ; save where Ur at
mov BP,SP ; going in.....
push DI
push SI
push CX ; not really needed for MSC but kinda
; nice to do cuz someone else might
; want to use the function and we do
; use CX later on
call ndp_type ; check for math coprocessor (NDP) type
; and hold that result in AX
pop CX ; put things back the way that you
pop SI ; found 'em when you started this
pop DI ; little drill off.....
pop BP
; AND
ret ; go back to where you came from....
; ( ===> the calling program )
; with Ur results sittin' in AX !!
even
control dw 0 ; control word needed for the NDP test
CoPro endp
; Check for an NDP.
;
ndp_type PROC
do_we: fninit ; try to initialize the NDP
mov byte ptr control+1,0 ; clear memory byte
fnstcw control ; put control word in memory
mov AH,byte ptr control+1 ; iff AH is 03h, you got
cmp AH,03h ; an NDP on board !!
je chk_87 ; found somethin', keep goin'
xor AX,AX ; clean out AX to show a zero
jmp SHORT NDPbye ; return (i.e., no NDP)
; 'got an 8087 ??
chk_87: and control,NOT 0080h ; turn ON interrupts (IEM = 0)
fldcw control ; load control word
fdisi ; turn OFF interrupts (IEM = 1)
fstcw control ; store control word
test control,0080h ; iff IEM=1, 8087
jz chk287 ; 'guess not! March on....
mov Ax,1 ; set up for a 1 return to
jmp SHORT NDPbye ; show an 8087 is on board
; if not.... would you believe an 80287 maybe ??
.286
CHK287: finit ; set default infinity mode
fld1 ; make infinity
fldz ; by dividing
fdiv ; 1 by zero !!
fld st ; now make a
fchs ; negative infinity
fcompp ; compare Ur two infinities
fstsw control ; iff, for 8087 or 80287
fwait ; sit tight 'til status word is put away
mov AX,control ; getchur control word
sahf ; putchur AH into flags
jnz got387 ; NO GOOD.... march on !!
mov Ax,2 ; gotta be a 80287 cuz we already tested
jmp SHORT NDPbye ; for an 8087
; We KNOW that there is an NDP on board otherwise we would have bailed
; out after 'do_we'. It isn't an 8087 or an 80287 or we wouldn't have
; gotten this far. It's gotta be an 80387 !!
got387: mov ax,3 ; call it an 80387 and return 3
NDPbye: ret ; and go back where you came from
; (i.e., ===> _chips) carrying the NDP
; type in Ur DL register
ndp_type endp
code ends
end